using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Security.Permissions;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using Core.BOL;
using Core.DAL;
using Core.Extentions;
using Core.Utils;
using ScoutNET.ActionsResults;
using ScoutNET.Attributes;

namespace ScoutNET.Controllers
{
    public class GalerieController : ApplicationController
    {
        #region Repositories
        private SectionRepository sr = new SectionRepository();
        private GMapPlaceRepository gpr = new GMapPlaceRepository();
        private AlbumsRepository ar = new AlbumsRepository();
        private ImagesRepository ir = new ImagesRepository();
        #endregion

        #region Views
        [AuthorizeView(ErrorMessageKey = "Galerie_Index_Error_Acces", ShowToCrawler = true)]
        public ActionResult Index(string systemName, int? page)
        {
            string section = sr.GetSectionNameBySystemName(systemName);
            ViewData["PageTitle"] = Resources.Galerie_Index_Title.Replace("[SECTION]", section.ToLower());
            ViewData["PageDescription"] = Resources.Galerie_Index_Description.Replace("[SECTION]", section.ToLower());
            ViewData["Summary"] = Resources.Galerie_Index_Summary.Replace("[NUMGALLERY]", ar.GetCountAlbums(systemName).ToString()).Replace("[NUMPICTURE]", ir.GetCountImages(systemName).ToString());
            ViewData["SystemName"] = systemName;
            ViewData["UserType"] = UsersRepository.GetUserType(systemName);

            string[] saBreadcrumb = new string[2];
            saBreadcrumb[0] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Master_Breadcrumb_Home, "Default", "Index", "Home", null, null);
            saBreadcrumb[1] = Resources.Galerie_Index_Breadcrumb.Replace("[SECTION]", section.ToLower());
            ViewData["Breadcrumb"] = saBreadcrumb;

            int itemPage = 6;
            double totalItems = Convert.ToDouble(ar.GetCountAlbums(systemName));
            int totalPages = (int)Math.Ceiling(totalItems / itemPage);
            int pageID = (page == null || page == 0) ? 1 : (int)page;
            pageID = (page > totalPages) ? totalPages : pageID;
            int skipItem = (pageID - 1) * itemPage;
            List<vw_Site_Photos_Album> lAlbum = ar.GetAlbumBySectionName(systemName, skipItem, itemPage);
            if (!User.IsInRole("Animateur") && !User.IsInRole("C.U"))
            {
                lAlbum = lAlbum.Where(p => p.ImageCount > 0).ToList();
            }

            if(lAlbum.Count > 0)
            {
                ViewData["TotalPages"] = totalPages;
                ViewData["TotalItems"] = lAlbum.Count;
                ViewData["Page"] = pageID;
                
                return View("Index", lAlbum);
            }
            else
            {
                ViewData["ErrorMessage"] = Resources.Galerie_Index_Error_NoItem.Replace("[SECTION]", section);
                return View("Error");
            }
        }

        [Authorize(Roles = "Animateur,C.U")]
        public ActionResult Create(string systemName, Guid? ID)
        {
            // Redirect to admin section
            string adminSection = UsersRepository.GetAdminSection(systemName);
            string role = string.Empty;
            if (systemName != adminSection && UsersRepository.GetUserType(systemName, out role) != UserType.Administrator)
            {
                return RedirectToAction("Create", new { systemName = adminSection });
            }
            ViewData["SystemName"] = adminSection;

            // Meta Tag
            string section = sr.GetSectionNameBySystemName(systemName).ToLower();
            ViewData["PageTitle"] = Resources.Galerie_Create_Title.Replace("[SECTION]", section);
            ViewData["PageDescription"] = Resources.Galerie_Create_Description;

            //Breadcrumb
            string[] saBreadcrumb = new String[3];
            saBreadcrumb[0] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Master_Breadcrumb_Home, "Default", "Index", "Home", null, null);
            saBreadcrumb[1] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Galerie_Index_Breadcrumb.Replace("[SECTION]", section), "SectionIndex", "Index", "Galerie", new RouteValueDictionary(new { systemName = systemName.UppercaseFirst() }), null);
            saBreadcrumb[2] = Resources.Galerie_Create_Breadcrumb;
            ViewData["Breadcrumb"] = saBreadcrumb;

            ViewData["SlSection"] = new SelectList(sr.GetNonAdministrativeSections(), "ID", "Section");
            ViewData["Folder"] = ConfigurationManager.AppSettings["GalleryPath"] + ID.ToString();
            ViewData["DefaultImage"] = null;
            ViewData["MaxRequestLength"] = Files.GetMaxRequestLength();
            ViewData["DefaultImageID"] = Guid.NewGuid().ToString();
            ViewData["FormsToken"] = Request.Cookies[FormsAuthentication.FormsCookieName] == null ? string.Empty : Request.Cookies[FormsAuthentication.FormsCookieName].Value;
            ViewData["GMapPlace"] = GetGMapPlaceSelectList(systemName, null); 

            return View("Create");
        }

        [Authorize(Roles = "Animateur,C.U")]
        [HttpPost]
        public ActionResult Create(string systemName, FormCollection fc)
        {
            // Redirect to admin section
            string adminSection = UsersRepository.GetAdminSection(systemName);
            string role = string.Empty;
            if (systemName != adminSection && UsersRepository.GetUserType(systemName, out role) != UserType.Administrator)
            {
                return RedirectToAction("Create", new { systemName = adminSection });
            }
            ViewData["SystemName"] = adminSection;

            // Meta Tag
            string section = sr.GetSectionNameBySystemName(systemName).ToLower();
            ViewData["PageTitle"] = Resources.Galerie_Create_Title.Replace("[SECTION]", section);
            ViewData["PageDescription"] = Resources.Galerie_Create_Description;

            //Breadcrumb
            string[] saBreadcrumb = new String[3];
            saBreadcrumb[0] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Master_Breadcrumb_Home, "Default", "Index", "Home", null, null);
            saBreadcrumb[1] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Galerie_Index_Breadcrumb.Replace("[SECTION]", section), "SectionIndex", "Index", "Galerie", new RouteValueDictionary(new { systemName = systemName.UppercaseFirst() }), null);
            saBreadcrumb[2] = Resources.Galerie_Create_Breadcrumb;
            ViewData["Breadcrumb"] = saBreadcrumb;

            if (ValidateGallery(fc))
            {
                // Create Album
                int sectionID = sr.GetSectionID(systemName);
                Guid IID = Guid.NewGuid();
                tSite_Photos_Album album = new tSite_Photos_Album();
                album.Description = fc["Description"];
                album.Title = fc["Title"];
                album.InsertDate = DateTime.Now.GetNowTimeByTimeZone();
                album.SID = sectionID;
                ar.InsertAlbum(album);
                ar.Save();

                int GID = -1;
                if (int.TryParse(fc["ddlGMapPlaces"], out GID))
                {
                    gpr.ConnectAlbumToPlace(album.ID, GID);
                    gpr.Save();
                }

                // Create album folder
                string folder = this.Server.MapPath(ConfigurationManager.AppSettings["GalleryPath"] + album.ID.ToString("D6") + "/");
                if (!Directory.Exists(folder))
                {
                    Directory.CreateDirectory(folder);
                }

                string imageName = IID.ToString() + ".jpg";
                using (FileStream fsImage = new FileStream(folder + imageName, System.IO.FileMode.Create))
                {
                    byte[] baImage = (byte[])Session["DefaultImage"];
                    fsImage.Write(baImage, 0, baImage.Length);
                }

                //  Add image to album
                tSite_Photos_Image image = new tSite_Photos_Image();
                image.AID = album.ID;
                image.SID = sectionID;
                image.ImageName = IID;
                ir.InsertImage(image);
                ir.Save();

                album.DefaultImage = image.ID;
                ar.Save();

                return RedirectToAction("Create", "Album", new { systemName = systemName, ID = album.ID });
            }
            else
            {
                ViewData["DefaultImage"] = (byte[])this.Session["DefaultImage"];
                ViewData["DefaultImageID"] = Guid.NewGuid().ToString();
                ViewData["MaxRequestLength"] = Files.GetMaxRequestLength();
                ViewData["FormsToken"] = Request.Cookies[FormsAuthentication.FormsCookieName] == null ? string.Empty : Request.Cookies[FormsAuthentication.FormsCookieName].Value;
                ViewData["GMapPlace"] = GetGMapPlaceSelectList(systemName, null); 

                return View("Create");
            }
        }

        [Authorize(Roles = "Animateur,C.U")]
        public ActionResult Edit(string systemName, int ID)
        {
            // Redirect to admin section
            string adminSection = UsersRepository.GetAdminSection(systemName);
            string role = string.Empty;
            if (systemName != adminSection && UsersRepository.GetUserType(systemName, out role) != UserType.Administrator)
            {
                return RedirectToAction("Index", new { systemName = adminSection });
            }
            ViewData["SystemName"] = adminSection;

            tSite_Photos_Album a = ar.GetAlbumByID(ID);
            string folder = string.Empty;
            tSite_Photos_Image i = null;
            if (a.DefaultImage != null)
            {
                i = ir.GetImageByID((int)a.DefaultImage);
                folder = Server.MapPath(ConfigurationManager.AppSettings["GalleryPath"]);
                folder = folder + a.ID.ToString("D6") + "\\" + i.ImageName + ".jpg";
            }

            tSite_GMapPlace place = gpr.GetPlaceByAlbumID(a.ID);
            int GID = (place != null) ? place.ID : -1;

            // Meta Tag
            string section = sr.GetSectionNameBySystemName(systemName).ToLower();
            ViewData["PageTitle"] = Resources.Galerie_Edit_Title.Replace("[ALBUM_NAME]", a.Title);
            ViewData["PageDescription"] = Resources.Galerie_Create_Description;

            //Breadcrumb
            string[] saBreadcrumb = new String[3];
            saBreadcrumb[0] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Master_Breadcrumb_Home, "Default", "Index", "Home", null, null);
            saBreadcrumb[1] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Galerie_Index_Breadcrumb.Replace("[SECTION]", section), "SectionIndex", "Index", "Galerie", new RouteValueDictionary(new { systemName = systemName.UppercaseFirst() }), null);
            saBreadcrumb[2] = Resources.Galerie_Edit_Breadcrumb.Replace("[ALBUM_NAME]", a.Title);
            ViewData["Breadcrumb"] = saBreadcrumb;

            ViewData["SlSection"] = new SelectList(sr.GetNonAdministrativeSections(), "ID", "Section");
            ViewData["Folder"] = ConfigurationManager.AppSettings["GalleryPath"] + ID.ToString();
            Session["DefaultImage"] = (a.DefaultImage != null) ? System.IO.File.ReadAllBytes(folder) : null;
            ViewData["MaxRequestLength"] = Files.GetMaxRequestLength();
            ViewData["DefaultImageID"] = (i != null) ? i.ImageName.ToString() : null;
            ViewData["FormsToken"] = Request.Cookies[FormsAuthentication.FormsCookieName] == null ? string.Empty : Request.Cookies[FormsAuthentication.FormsCookieName].Value;
            ViewData["GMapPlaces"] = GetGMapPlaceSelectList(systemName, GID); 

            return View(a);
        }

        [HttpPost]
        [Authorize(Roles = "Animateur,C.U")]
        public ActionResult Edit(string systemName, int ID, FormCollection fc)
        {
            // Redirect to admin section
            string adminSection = UsersRepository.GetAdminSection(systemName);
            string role = string.Empty;
            if (systemName != adminSection && UsersRepository.GetUserType(systemName, out role) != UserType.Administrator)
            {
                return RedirectToAction("Index", new { systemName = adminSection });
            }
            ViewData["SystemName"] = adminSection;

            // Meta Tag
            string section = sr.GetSectionNameBySystemName(systemName).ToLower();
            ViewData["PageTitle"] = Resources.Galerie_Edit_Title.Replace("[ALBUM_NAME]", fc["title"]);
            ViewData["PageDescription"] = Resources.Galerie_Create_Description;

            //Breadcrumb
            string[] saBreadcrumb = new String[3];
            saBreadcrumb[0] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Master_Breadcrumb_Home, "Default", "Index", "Home", null, null);
            saBreadcrumb[1] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Galerie_Index_Breadcrumb.Replace("[SECTION]", section), "SectionIndex", "Index", "Galerie", new RouteValueDictionary(new { systemName = systemName.UppercaseFirst() }), null);
            saBreadcrumb[2] = Resources.Galerie_Create_Breadcrumb;
            ViewData["Breadcrumb"] = saBreadcrumb;

            if (ValidateGallery(fc))
            {
                tSite_Photos_Album a = ar.GetAlbumByID(ID);
                a.Description = fc["description"];
                a.Title = fc["title"];
                ar.Save();

                int GID = -1;
                if (int.TryParse(fc["ddlGMapPlaces"], out GID))
                {
                    gpr.ConnectAlbumToPlace(a.ID, GID);
                    gpr.Save();
                }

                ViewData["ValidationMessage"] = Resources.Gallerie_Edit_Validation.Replace("[USERNAME]", User.Identity.Name.UppercaseFirst());
                return View("Validation");
            }
            else
            {
                ViewData["DefaultImage"] = (byte[])this.Session["DefaultImage"];
                ViewData["MaxRequestLength"] = Files.GetMaxRequestLength();
                ViewData["FormsToken"] = Request.Cookies[FormsAuthentication.FormsCookieName] == null ? string.Empty : Request.Cookies[FormsAuthentication.FormsCookieName].Value;
                
                return View("Create");
            }
        }

        public UploadPicturesResult UploadImage(HttpPostedFileBase fileData, Guid ID, string token)
        {
            FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(token);
            if (ticket != null)
            {
                var identity = new FormsIdentity(ticket);
                if (identity.IsAuthenticated)
                {
                    string folder = ConfigurationManager.AppSettings["TempPath"] + "/";
                    string imageName = ID.ToString() + ".jpg";

                    return new UploadPicturesResult(fileData, folder, imageName, ImageMode.GalleryPhoto);
                }
            }
            return null;
        }

        [Authorize(Roles = "Animateur,C.U")]
        [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)]
        public FileResult DefaultImage(Guid ID)
        {
            string filePath = Server.MapPath(ConfigurationManager.AppSettings["TempPath"] + "/" + ID.ToString() + ".jpg");
            byte[] baImage = null;

            if (System.IO.File.Exists(filePath))
            {
                baImage = System.IO.File.ReadAllBytes(filePath);
                Session["DefaultImage"] = baImage;
            }
            else
            {
                baImage = (byte[])this.Session["DefaultImage"];
            }
            

            if (baImage != null)
            {
                Dictionary<string, int> dImageSize = Imaging.GetImageSize(ImageMode.GalleryThumbnail);
                baImage = Imaging.ResizeImage(baImage, dImageSize["W"], dImageSize["H"], 100);
                
                System.IO.File.Delete(filePath);
                
                return new FileContentResult(baImage, "image/jpeg");
            }
            return null;
        }

        [AuthorizeView(ShowToCrawler = true)]
        [OutputCache(CacheProfile="Photo")]
        [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)]
        public ActionResult ImageResize(int? ID, string title)
        {
            if (ID != null)
            {
                byte[] baImage = Imaging.GetResizedImage((int)ID, ImageMode.GalleryThumbnail, true);

                return new FileContentResult(baImage, "image/jpeg");
            }
            else
            {
                return View("Error404");
            }
        }

        [HttpPost]
        [Authorize(Roles = "Animateur,C.U")]
        public EmptyResult ClearDefaultImage()
        {
            this.Session["DefaultImage"] = null;

            return new EmptyResult();
        }
        #endregion

        #region Methodes
        private SelectList GetGMapPlaceSelectList(string systemName, int? selectetdItem)
        {
            List<tSite_GMapPlace> lGMapPlace = gpr.GetMarkersBySectionName(systemName, -1, -1);
            var slConvoc = (from c in lGMapPlace
                            select new
                            {
                                ID = c.ID,
                                Title = c.Label + " ( " + c.DateCamp + " )"
                            }).ToList();

            return new SelectList(slConvoc, "ID", "Title", selectetdItem);
        }

        private bool ValidateGallery(FormCollection fc)
        {
            ModelState.SetModelValue("title", ValueProvider.GetValue("title"));
            ModelState.SetModelValue("description", ValueProvider.GetValue("description"));
            ModelState.SetModelValue("imageUploaded", ValueProvider.GetValue("imageUploaded"));
            ModelState.SetModelValue("GMapPlace", ValueProvider.GetValue("GMapPlace"));

            if ((String.IsNullOrEmpty(fc["imageUploaded"]) || fc["imageUploaded"] == "0") && (byte[])this.Session["DefaultImage"] == null)
            {
                ModelState.AddModelError("", Resources.Galerie_Create_Error_DefaultImage);
            }

            if (String.IsNullOrEmpty(fc["title"]))
            {
                ModelState.AddModelError("title", Resources.Galerie_Create_Error_Title);
            }

            if (String.IsNullOrEmpty(fc["description"]))
            {
                ModelState.AddModelError("description", Resources.Galerie_Create_Error_Description);
            }

            return ModelState.IsValid;
        }
        #endregion
    }
}
